<template>
	<view class="container" @tap="togglePicker(0)">
		<!-- <view style="width: 100%;height: 60px;">
		</view> -->
		<u-navbar :title="userName" @rightClick="rightClick" :autoBack="true">
		</u-navbar>
		<!--内容-->
		<view class="scroll" :style="{height: scrollHeight}">
			<scroll-view :scroll-into-view="scrollViewId" scroll-y
				style="height: 100%;padding-top: 60px;box-sizing: border-box;">
				<view class="item-space"></view>
				<!-- <view class="time">晚上 10:04</view> -->
				<view v-for="(item, index) in list" :key="index">
					<!--撤销-->
					<!-- <view class="">
						 {{index}}
					</view> -->
					<view v-if="item.msgType == 'cancel'" class="cancel">
						<text v-if="item.fromUserId == fromUserId" class="text">你撤回了一条消息</text>
						<text v-else class="text">成员 {{ item.fromUserId }} 撤回了一条消息</text>
					</view>
					<view v-else class="item flex-row" :class="[item.fromUserId == fromUserId ? 'right' : 'left']">
						<!--处理头像-->
						<view v-if="item.fromUserId == fromUserId">
							<image v-if="fromUserFace" :src="fromUserFace" class="face"></image>
							<image v-else src="../../static/img/face.png" class="face"></image>
						</view>
						<view v-else>
							<image v-if="toUserFace" :src="toUserFace" class="face"></image>
							<image v-else src="../../static/img/face.png" class="face"></image>
						</view>
						<!--文本-->
						<view v-if="item.msgType == 'text'" @longpress="longPress(item)" class="content flex-row">
							{{ item.content }}</view>
						<!--图片-->
						<image v-if="item.msgType == 'image'" @longpress="longPress(item)" :src="item.content"
							mode="widthFix" style="width: 320upx;" @click="bigImg(item.content)"></image>
						<!--地图-->
						<view v-if="item.msgType == 'map'" class="content map" @tap="openLocation(item.content)">
							<view class="title">{{ item.content.address }}</view>
							<map class="box" :latitude="item.content.latitude" :longitude="item.content.longitude"
								:markers="[{latitude: item.content.latitude, longitude: item.content.longitude, iconPath: '../../static/img/marker.png'}]"
								@tap="openLocation(item.content)"></map>
						</view>
						<!--语音-->
						<view v-if="item.msgType == 'voice'" @tap="playVoice(item)" class="content">
							<image v-show="voicePlayingId != item.id" src="../../static/img/audio.png"
								class="voice-icon"></image>
							<image v-show="voicePlayingId == item.id" src="../../static/img/audio-play.gif"
								class="voice-icon"></image>
						</view>
					</view>
				</view>
				<view id="bottom"></view>
			</scroll-view>
		</view>
		<!--输入-->
		<view class="oper flex-row" @tap.prevent.stop="">
			<!--语音切换-->
			<image v-show='buttonShow' v-if="isEdit" @tap="toggleEdit(false)" src="../../static/img/voice-circle.png"
				class="icon"></image>
			<image v-else @tap="toggleEdit(true)" src="../../static/img/keyboard.png" class="icon"></image>
			<!-- 快捷短语 -->
			<image v-if="isEdit" @tap="togglePicker(200, 'QuickPhrases')" src="../../static/img/tabbar/message.png"
				class="icon"></image>
			<!--语音切换-->
			<input v-if="isEdit" @focus="inputFocus" :focus="isFocus" :cursor-spacing="8" :adjust-position="false"
				type="text" v-model="content" class="input" placeholder="请输入内容" />
			<view v-else @touchstart="startVoice" @touchend="endVoice" class="input" style="text-align: center;">按住开始说话
			</view>

			<!--表情-->
			<image @tap="togglePicker(200, 'emoji')" src="../../static/img/emoji.png" class="icon"></image>
			<!--发送-->
			<view @touchend.prevent="send" v-show="content" class="btn">发送</view>
			<!--附件-->
			<image @tap="togglePicker(86, 'file')" v-show="!content" src="../../static/img/add.png" class="icon">
			</image>
		</view>
		<!--快捷短语-->
		<view v-show="show" class="QuickPhrases" @tap.prevent.stop="">
			<view class="list">
				<view class="QuickPhrases" @tap="content += item.connect" v-for="(item, index) in QuickPhrasesList"
					:key="index" @click="QuickPhrases(item)">{{ item.connect }}
					<u-divider></u-divider>
				</view>

			</view>
		</view>
		<!--表情-->
		<view v-show="showEmoji" class="emoji" @tap.prevent.stop="">
			<view class="list">
				<view class="item" @tap="content += item" v-for="(item, index) in emojis" :key="index">{{ item }}</view>
			</view>
		</view>
		<!--附件-->
		<view v-show="showFile" class="file" @tap.prevent.stop="">
			<view class="list flex-row">
				<view class="item flex-column" @tap="uploadImage(['album'])">
					<image src="../../static/img/album.png" mode="widthFix" class="icon"></image>
					<view class="text">相册</view>
				</view>
				<view class="item flex-column" @tap="uploadImage(['camera'])">
					<image src="../../static/img/photo.png" mode="widthFix" class="icon"></image>
					<view class="text">拍照</view>
				</view>
				<view class="item flex-column" v-show='buttonShow' @tap="getLocation">
					<image v-show='buttonShow' src="../../static/img/location.png" mode="widthFix" class="icon"></image>
					<view v-show='buttonShow' class="text">位置</view>
				</view>
			</view>
		</view>
		<!--语音-->
		<my-voice v-show="showVoice"></my-voice>
	</view>
</template>

<script>
	import emoji from '../../plugins/emoji.js'
	import myVoice from '../../components/self-voice/index.vue'

	const innerAudioContext = uni.createInnerAudioContext()
	const recorderManager = uni.getRecorderManager()
	export default {
		components: {
			myVoice
		},
		data() {
			return {
				show: false, // 快捷短语
				buttonShow: true,
				emojis: [],
				isEdit: true,
				msgType: 'text',
				isFocus: false,
				showEmoji: false,
				showFile: false,
				showVoice: false,
				scrollHeight: 'auto', // 内容区域高度
				statusBarHeight: 0, // 状态栏高度
				scrollViewId: '', // 滚动到最底部
				voicePlayingId: '', // 正在播放的消息ID
				content: '', //消息内容
				list: [],
				socketOpen: false,
				socketMsgQueue: [],
				sender: 1,
				userName: '',
				toName: '',
				userList: '',
				// fromUserId: uni.getStorageSync('userId'),
				fromUserId: '',
				chat: '',
				fromUserFace: '',
				toUserFace: '',
				// fromUserFace: 'admin',
				toUserId: '',
				toUserName: '',
				QuickPhrasesList: [{
						id: 1,
						connect: '你好，我定位准确，请按时来接我'
					},
					{
						id: 2,
						connect: '你好，请晚十分钟来接我'
					},
					{
						id: 3,
						connect: '你好，我定位有误'
					}
				]
			}
		},
		mounted() {

			this.socket.emit('onchat', {
				name: this.toName,
				object: 'user'
			})
			this.socket.emit('chatLogin', {
				staffAcc: this.fromUserId,
				object: 'user'
			})
		},
		onLoad(option) {

			this.socket.on('connect', () => {
				// ws连接已建立，此时可以进行socket.io的事件监听或者数据发送操作
				// 连接建立后，本插件的功能已完成，接下来的操作参考socket.io官方客户端文档即可
				console.log('ws 已连接')
			});
			this.socket.on('chatLogin', (msg) => {
				console.log('ws收到服务器消息', msg)
			});

			//接受消息
			this.socket.on('message', (msg) => {
				console.log('ws收到服务器消息', msg)
				this.list.push({
					fromUserFace: msg.url,
					fromUserId: msg.name,
					toUserId: msg.toname,
					content: msg.content,
					msgType: msg.msgType,
					time: msg.time
				})
			});
			// 初始化内容高度
			this.setScrollHeight()

			// 初始化状态栏高度
			uni.getSystemInfo({
				success: res => {
					this.statusBarHeight = res.statusBarHeight
				}
			})

			// 结束录音
			recorderManager.onStop(res => {
				this.upload(res.tempFilePath)
			})

			// 结束播放
			innerAudioContext.onEnded(res => {
				this.voicePlayingId = ''
			})

			// 设置标题
			// uni.setNavigationBarTitle({ title: option.toUserName })

			// 获取参数
			this.toUserId = option.toUserId
			// this.userName = useroption.userName
			this.toUserName = option.toUserName
			this.emojis = emoji

			let useroption = uni.getStorageSync('userChat')
			console.log(useroption, 243)
			this.toName = useroption.userId
			this.userName = useroption.userName
			this.toUserFace = useroption.UserFace
			this.chat = useroption.chat

			this.userList = uni.getStorageSync('userTable')
			this.fromUserFace = this.userList.headPortrait
			this.fromUserId = this.userList.userId + 'user'
			console.log(this.toName, 169)
			console.log(this.userList, this.fromUserId, 170)
			if (this.toName == '客服') {
				this.buttonShow = false,
					this.toUserFace =
					'https://img-qn-2.51miz.com/preview/element/00/01/27/97/E-1279706-3813EBF9.jpg!/quality/90/unsharp/true/compress/true/format/jpg/fh/320'
				QuickPhrasesList: [{
						id: 1,
						connect: '你好，司机到点未到达怎么办'
					},
					{
						id: 2,
						connect: '你好，如何取消行程'
					},
					{
						id: 3,
						connect: '你好，付款失败怎么办'
					}
				]
			}

			// 获取消息记录
			this.getList()

		},
		onHide() {
			innerAudioContext.stop()
		},
		onBackPress() {
			if (this.showFile || this.showEmoji || this.show) {
				this.showFile = false
				this.showEmoji = false
				this.show = false
				this.setScrollHeight(0)
				return true
			}
			return false
		},
		methods: {
			// 发送消息
			send() {
				this.socket.emit('chat_msg', {
					// userId: 'admin',
					fromUserFace: 'https://img1.baidu.com/it/u=592570905,1313515675&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
					name: this.fromUserId,
					userName: this.userList.wxName,
					toname: this.toName,
					content: this.content,
					msgType: this.msgType,
					time: new Date(),
					object: 'user',
			 	position: 'left'
				})
				this.list.push({
					fromUserFace: '',
					fromUserId: this.fromUserId,
					toUserId: this.toName,
					content: this.content,
					msgType: this.msgType,
				})
				this.content = ''
				this.initScrollBar()
				// cb ? cb() : this.togglePicker(0, 'file')
			},
			QuickPhrases(item) {
				console.log(item.connect)
			},
			rightClick() {
				console.log('rightClick');
				if (this.toName == '客服') {
					uni.redirectTo({
						url: "/pages/my/my"
					})
				} else {
					uni.redirectTo({
						url: "/subpkg/userWaitDriver/userWaitDriver"
					})
				}
			},
			// 初始化滚动
			initScrollBar() {
				setTimeout(() => {
					this.scrollViewId = ''
					setTimeout(() => {
						this.scrollViewId = 'bottom'
						setTimeout(() => {
							this.scrollViewId = ''
						}, 100)
					}, 100)
				}, 100)
			},
			// 监听输入聚焦
			inputFocus(e) {
				this.setScrollHeight(e.detail.height)
				this.initScrollBar()

				uni.onKeyboardHeightChange(res => {
					this.setScrollHeight(res.height)
					this.initScrollBar()
				})
			},
			// 设置scroll的高度
			setScrollHeight(descHeight = 0) {
				// #ifdef MP-WEIXIN
				this.scrollHeight = `calc(100vh - 110rpx - ${descHeight}px)`
				// #endif
				// #ifdef APP-PLUS
				this.scrollHeight = `calc(100vh - 110upx - ${descHeight}px)`
				// #endif
				// #ifdef H5
				this.scrollHeight = `calc(100vh - 110upx - 88rpx - ${descHeight}px)`
				// #endif
			},
			// 切换选择
			togglePicker(height = 0, type = '') {
				this.showEmoji = false
				this.showFile = false
				this.show = false
				let status = height > 0 ? true : false

				switch (type) {
					case 'emoji':
						this.showEmoji = status;
						break
					case 'file':
						this.showFile = status;
						break
					case 'QuickPhrases':
						this.show = status;
						break
				}

				setTimeout(() => {
					this.setScrollHeight(height)
					this.initScrollBar()
				}, 50)
			},
			// 切换语音与编辑
			toggleEdit(bool) {
				this.isEdit = bool
				this.isFocus = bool
				this.setScrollHeight(0)
			},
			// 开始录音
			startVoice() {
				this.showVoice = true
				recorderManager.start()
			},
			// 结束录音
			endVoice() {
				this.showVoice = false
				recorderManager.stop()
			},
			// 上传
			upload(filePath) {
				console.log(filePath)
				uni.uploadFile({
					url: "http://localhost:8000/fileUpload",
					name: 'file',
					filePath,
					formData: {
						userId: this.fromUserId
					},
					// header: this.$util.getHeader(),
					success: res => {
						uni.hideLoading()
						let data = JSON.parse(res.data)
						console.log(data)
						// this.pushMessage(data.data, 'voice')
						this.msgType = 'voice'
						this.content = data.data
						this.send()
						this.msgType = 'text'
					},
					fail: err => {
						uni.hideLoading()
					}
				})
			},
			// 播放录音
			playVoice(item) {
				if (this.voicePlayingId) {
					this.voicePlayingId = ''
				} else {
					this.voicePlayingId = item.id
					innerAudioContext.src = item.content
					innerAudioContext.play()
				}
			},
			// 长按
			longPress(msg) {
				let data = {
					type: 'single',
					source: this.fromUserId,
					dest: this.toUserId,
					timestamp: new Date().getTime(),
					msg: {
						id: msg.id,
						fromUserId: msg.fromUserId,
						toUserId: msg.toUserId,
						type: 'cancel',
						content: msg.content
					}
				}

				uni.sendSocketMessage({
					data: JSON.stringify(data),
					success: res => {
						// 撤销本地消息
						this.list = this.list.map(item => {
							item.type = item.id == msg.id ? 'cancel' : item.type
							return item
						})
					}
				})
			},

			// 获取位置
			getLocation() {
				if (this.toName != '客服') {
					console.log(458)
					uni.getLocation({
						success: res => {
							console.log(res, 460)
							let {
								latitude,
								longitude
							} = res
							uni.chooseLocation({
								latitude,
								longitude,
								success: chooseRes => {
									// this.pushMessage(JSON.stringify(chooseRes), 'map')
									console.log(chooseRes)
									this.msgType = 'map'
									this.content = JSON.stringify(chooseRes)
									this.send()
									this.msgType = 'text'
								},
								fail(err) {
									console.log(err.errMsg,488)
								}
							})
						}
					})
				}

			},

			// // 获取位置
			// getLocation(){
			// 	console.log(456)
			// 	if(this.toName!= '客服'){
			// 		console.log(457)
			// 		uni.getLocation({
			// 			success: res=>{
			// 			let { latitude,longitude } = res
			// 				uni.chooseLocation({
			// 					latitude,
			// 					longitude,
			// 					success: chooseRes=>{
			// 						console.log(chooseRes)
			// 						this.msgType = 'map'
			// 						this.content = JSON.stringify(chooseRes)
			// 						this.send()
			// 						this.msgType = 'text'
			// 						console.log(471)
			// 					},
			// 					fail(err) {
			// 						console.log(err,'=======')
			// 					}
			// 				})
			// 		},
			// 		fail(err) {
			// 			console.log(err,'-------')
			// 		}
			// 	})
			// 	}
			// },
			// 打开位置
			openLocation(content) {
				let {
					latitude,
					longitude
				} = JSON.parse(content)
				uni.openLocation({
					latitude,
					longitude
				})
			},
			// 发送图片
			uploadImage(sourceType = ['album']) {
				uni.chooseImage({
					sourceType,
					success: chooseImageRes => {
						const tempFilePaths = chooseImageRes.tempFilePaths;
						tempFilePaths.forEach(temp => {
							// this.$util.loading('上传中')
							uni.uploadFile({
								url: "http://localhost:8000/fileUpload",
								filePath: temp,
								formData: {
									userId: this.fromUserId
								},
								name: 'file',
								// header: this.$util.getHeader(),
								success: uploadRes => {
									uni.hideLoading()
									let data = JSON.parse(uploadRes.data)
									console.log(data)
									this.msgType = 'image'
									this.content = data.data
									// this.pushMessage(data.data, 'image')
									this.send()
									this.msgType = 'text'
								},
								fail: err => {
									uni.hideLoading()
								}
							})
						})
					}
				})
			},

			// 点击放大
			bigImg(item) {
				console.log(495, item)
				wx.previewImage({
					urls: [item], //需要预览的图片http链接列表，多张的时候，url直接写在后面就行了
					current: '', // 当前显示图片的http链接，默认是第一个
					success: function(res) {},
					fail: function(res) {},
					complete: function(res) {},
				})
			},
			// 推送消息
			pushMessage(content, type = 'text', cb = () => {}) {
				// 本地保存
				uni.request({
					method: 'POST',
					// url: 'http://localhost:8000/RecordKeeping',
					data: msgData,
					// header: this.$util.getHeader(),
					success: res => {
						if (res.data.code) {
							return this.$util.toast(res.data.code)
						}
						let msgId = res.data.data

						// 判断是否为非文本
						if (!['text', 'map'].includes(type)) {
							msgData.content = this.$api.staticPath + msgData.content
						}
					}
				})
			},
			// 获取记录
			getList() {
				console.log(this.fromUserId, 548)
				uni.request({
					url: 'http://localhost:8000/getChatRecord',
					data: {
						sender: this.fromUserId,
						receiver: this.toName,
						object: 'user'
					},
					// header: this.$util.getHeader(),
					success: res => {
						console.log(res, 533)
						this.list = res.data.data.map(item => {
							item.fromUserId = item.sender
							item.toUserId = item.receiver
							item.msgType = item.msgType

							return item
						})
						console.log(this.list);

						this.scrollViewId = ''
						setTimeout(() => {
							this.scrollViewId = 'bottom'
							setTimeout(() => {
								this.scrollViewId = ''
							}, 100)
						}, 100)
					}
				})
			}
		}
	}
</script>

<style lang="scss" scoped>
	.container {
		height: 100vh;
		overflow: hidden;
	}

	/* #ifdef H5 */
	.container {
		height: calc(100vh - 88upx);
	}

	/* #endif */

	.status_bar,
	.container,
	.header,
	.emoji,
	.QuickPhrases,
	.file {
		background-color: #F3F3F3;
	}

	.header {
		border-bottom: 2upx solid #EEE;

		.center {
			font-weight: bold;
		}
	}

	.map {
		width: 60%;
		height: 300upx;
		background-color: #FFF !important;

		&::before {
			border-right: 30upx solid #FFF !important;
		}

		.title {
			height: 80upx;
			font-size: 28upx;
			overflow: hidden;
			text-overflow: ellipsis;
			display: -webkit-box;
			-webkit-line-clamp: 2;
			-webkit-box-orient: vertical;
		}

		.box {
			width: 100%;
			height: 170upx;
			margin-top: 10upx;
		}
	}

	.emoji {
		height: 400upx;
		padding: 0 0 20upx 20upx;
		position: relative;

		.list {
			width: 100%;
			height: 400upx;
			padding: 20upx 0;
			overflow-y: auto;

			.item {
				float: left;
				display: block;
				height: 60upx;
				line-height: 60upx;
				width: calc(100% / 12);
				margin-right: 20upx;
			}
		}
	}

	.QuickPhrases {
		width: 90%;
		text-align: center;
		margin: 0 auto;
	}

	.file {
		padding: 30upx 20upx;

		.list {
			overflow: hidden;
			padding-left: 10upx;
			justify-content: flex-start;
		}

		.item {
			float: left;
			width: 110upx;
			height: 110upx;
			border-radius: 10upx;
			margin-right: 40upx;
			background-color: #FFF;

			.icon {
				width: 50upx;
			}

			.text {
				font-size: 24upx;
				margin-top: 4upx;
			}
		}
	}

	.oper {
		height: 110upx;
		padding: 0 20upx;
		box-sizing: border-box;
		border-top: 2upx solid #EEE;
		border-bottom: 2upx solid #EEE;

		.input {
			height: 68upx;
			line-height: 68upx;
			padding: 0 20upx;
			font-size: 28upx;
			border-radius: 10upx;
			background-color: #fff;
			width: calc(100% - 120upx - 20upx - 40upx - 60upx);
		}

		.icon {
			width: 60upx;
			height: 60upx;
		}

		.btn {
			color: #fff;
			width: 90upx;
			height: 52upx;
			font-size: 24upx;
			line-height: 52upx;
			text-align: center;
			border-radius: 10upx;
			background-color: #2BA245;
		}
	}

	.scroll {
		overflow-y: auto;
		transition: all 0.1s ease;
		height: calc(100vh - 88upx - 110upx - var(--status-bar-height));

		/* #ifdef MP-WEIXIN */
		height: calc(100vh - 88upx - var(--status-bar-height));
		/* #endif */
		/* #ifdef H5 */
		height: calc(100vh - 88upx - 110upx - var(--status-bar-height));
		/* #endif */

		.item-space {
			height: 30upx;
		}

		.time {
			color: #666;
			font-size: 24upx;
			text-align: center;
			margin-bottom: 20upx;
		}

		.cancel {
			width: 100%;
			height: 40upx;
			text-align: center;
			margin-bottom: 30upx;

			.text {
				color: #999;
				font-size: 24upx;
			}
		}

		.item {
			margin: 0 30upx 30upx;
			align-items: flex-start;
			justify-content: flex-start;

			.face {
				width: 80upx;
				height: 80upx;
				border-radius: 10upx;
			}

			.content {
				color: #000;
				font-size: 32upx;
				min-height: 80upx;
				border-radius: 10upx;
				padding: 20upx 24upx;
				background-color: #fff;
				word-break: break-all;
				word-wrap: break-word;
				max-width: calc(100% - 100upx - 120upx);
				position: relative;

				&::before {
					content: '';
					width: 0;
					height: 0;
					border-right: 30upx solid #FFF;
					border-top: 20upx solid transparent;
					border-bottom: 20upx solid transparent;
					position: absolute;
					top: 24upx;
				}

				.voice-icon {
					width: 32upx;
					height: 40upx;
					margin-right: 180upx;
					margin-bottom: -8upx;
				}
			}

			&.left {
				.face {
					margin-right: 30upx;
				}

				.content::before {
					left: -20upx;
				}
			}

			&.right {
				flex-direction: row-reverse;

				.face {
					margin-left: 30upx;
				}

				.content {
					background-color: #A0EA6F;

					&::before {
						right: -20upx;
						transform: rotate(180deg);
						border-right: 30upx solid #A0EA6F;
					}

					.voice-icon {
						margin-right: 0;
						margin-left: 180upx;
						transform: rotate(180deg);
					}
				}
			}
		}

		#bottom {
			height: 0;
		}
	}

	scroll-view,
	swiper,
	swiper-item,
	view,
	text,
	input,
	textarea {
		margin: 0;
		padding: 0;
		color: #333;
		font-size: 32upx;
		box-sizing: border-box;
	}

	/*全局容器*/
	.container {
		height: 100vh;
	}

	/* #ifdef H5 */
	.container {
		height: calc(100vh - 100upx);
	}

	/* #endif */

	/*flex布局*/
	.flex-row {
		display: flex;
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
	}

	.flex-column {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	/*文字省略*/
	.text-ellipsis {
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}

	/*状态栏*/
	.status_bar {
		color: #000;
		height: var(--status-bar-height);
		background-color: #fff;
	}

	/*间隔*/
	.space {
		height: 20upx;
		background-color: #F7F7F7;
	}

	/*NAV*/
	.header {
		display: flex;
		align-items: center;
		justify-content: space-between;
		height: 88upx;
		padding: 0 30upx;
		background-color: #fff;
	}

	.header .left,
	.header .right {
		width: 220upx;
	}

	.header .center {
		text-align: center;
		overflow: hidden;
		white-space: nowrap;
		text-overflow: ellipsis;
		width: calc(100% - 440upx);
	}

	.header .right {
		text-align: right;
	}

	.header .nav-title {
		font-size: 32upx;
	}

	/* 头部*/
	.head {
		height: 100upx;
		padding: 0 40upx;
	}

	.head .title {
		color: #000;
		font-size: 48upx;
		font-weight: bold;
	}

	.head .icon {
		width: 40upx;
		height: 40upx;
		margin-right: 6upx;
	}

	.head .text {
		color: #333;
		font-size: 32upx;
	}
</style>
